package com.lty.jeeg.server.modules.tms.service.impl;

import com.google.common.collect.Lists;
import com.lty.jeeg.server.common.page.table.PageTableHandler;
import com.lty.jeeg.server.common.page.table.PageTableRequest;
import com.lty.jeeg.server.common.page.table.PageTableResponse;
import com.lty.jeeg.server.common.utils.DateUtils;
import com.lty.jeeg.server.common.utils.UserUtil;
import com.lty.jeeg.server.modules.sys.dao.DictDao;
import com.lty.jeeg.server.modules.sys.dao.FileInfoDao;
import com.lty.jeeg.server.modules.sys.dao.UserDao;
import com.lty.jeeg.server.modules.sys.model.FileInfo;
import com.lty.jeeg.server.modules.sys.model.User;
import com.lty.jeeg.server.modules.sys.service.impl.BaseService;
import com.lty.jeeg.server.modules.tms.dao.ProjectDao;
import com.lty.jeeg.server.modules.tms.dao.TaskAtUsersDao;
import com.lty.jeeg.server.modules.tms.model.Matters;
import com.lty.jeeg.server.modules.tms.model.Project;
import com.lty.jeeg.server.modules.tms.model.Task;
import com.lty.jeeg.server.modules.tms.model.TaskAtUsers;
import com.lty.jeeg.server.modules.tms.service.MattersService;
import com.lty.jeeg.server.modules.tms.service.TaskAtUsersService;
import com.lty.jeeg.server.modules.tms.service.TaskService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lty.jeeg.server.modules.tms.dao.TaskDao;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author : LTY
 * @date : 2019-03-26 10:53:09
 * Description :
 */
@Service
@Slf4j
public class TaskServiceImpl implements TaskService {

    private final TaskDao taskDao;

    private final MattersService mattersService;

    private final ProjectDao projectDao;

    private final DictDao dictDao;

    private final UserDao userDao;

    private final TaskAtUsersService taskAtUsersService;

    private final FileInfoDao fileInfoDao;

    @Autowired
    public TaskServiceImpl(TaskDao taskDao, ProjectDao projectDao, MattersService mattersService, DictDao dictDao,UserDao userDao, TaskAtUsersService taskAtUsersService, FileInfoDao fileInfoDao) {
        this.taskDao = taskDao;
        this.projectDao = projectDao;
        this.mattersService = mattersService;
        this.dictDao = dictDao;
        this.userDao = userDao;
        this.taskAtUsersService = taskAtUsersService;
        this.fileInfoDao = fileInfoDao;
    }

    @Override
    public Task getById(Long id) {
        Task task = taskDao.getById(id);
        String screenshotPath = task.getScreenshotPath();
        if (StringUtils.isNotEmpty(screenshotPath)) {
            List<FileInfo> screenshots = Lists.newArrayList();
            String[] screenshotArray = screenshotPath.substring(1).split("\\|");
            for (String fileId: screenshotArray) {
                screenshots.add(fileInfoDao.getById(fileId));
            }
            task.setScreenshotPaths(screenshots);
        }
        return task;
    }

    @Override
    public List<Task> getByProjectId(Long projectId) {
        return taskDao.getByProjectId(projectId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delete(Long id) {
        log.debug("删除Task=>{}", id);
        //设置日期格式
        String msg = "删除了任务";
        Matters matters = new Matters();
        matters.setTaskId(id);
        matters.setMsg(msg);
        matters.preInsert();
        mattersService.save(matters);
        return taskDao.delete(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(Task task) {
        task.preUpdate();
        log.debug("修改Task=>{}", task.getId());

        // 保存@Users
        taskAtUsersService.deleteByTaskIdAndMattersId(task.getId(), 0L);
        if (task.getAtUsers() != null) {
            for (Long userId : task.getAtUsers()) {
                taskAtUsersService.save(new TaskAtUsers(task.getId(), 0L, userId));
            }
        }

        // 保存动态
        Matters matters = new Matters();
        matters.setTaskId(task.getId());
        matters.setMsg("更新了任务");
        mattersService.save(matters);

        return taskDao.update(task);
    }

    /**
     * 修改任务状态
     *
     * @param id     任务ID
     * @param status 任务状态
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeStatus(Long id, Integer status) {
        Task taskBefore = taskDao.getById(id);
        String statusBefore = dictDao.getByTypeAndK("task_status", taskBefore.getStatus().toString()).getVal();
        String statusAfter = dictDao.getByTypeAndK("task_status", status.toString()).getVal();
        String msg = "修改任务状态 " + statusBefore + " => " + statusAfter;
        Matters matters = new Matters();
        matters.setTaskId(id);
        matters.setMsg(msg);
        matters.preInsert();
        mattersService.save(matters);
        return taskDao.changeStatus(id, status);
    }
    /**
     * 修改任务优先级
     *
     * @param id     任务ID
     * @param grade 任务优先级
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeGrade(Long id, Integer grade) {
        Task taskBefore = taskDao.getById(id);
        //修改前优先级
        String gradeBefore = dictDao.getByTypeAndK("dept_level", taskBefore.getGrade().toString()).getVal();
        //修改后优先级
        String gradeAfter = dictDao.getByTypeAndK("dept_level", grade.toString()).getVal();
        String msg = "修改优先级 " + gradeBefore + " => " + gradeAfter;
        Matters matters = new Matters();
        matters.setTaskId(id);
        matters.setMsg(msg);
        matters.preInsert();
        mattersService.save(matters);
        return taskDao.changeGrade(id, grade);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeParticipant(Long id, String participantId) {
        //查询修改前信息
        Task taskBefore = taskDao.getById(id);
        User user = userDao.getById(Long.parseLong(participantId));
        //修改前执行者
        String participantBefore = taskBefore.getParticipantName();
        //修改后执行者
        String participantAfter = user.getNickname();
        String msg = "修改执行者 " + participantBefore + " => " + participantAfter;
        Matters matters = new Matters();
        matters.setTaskId(id);
        matters.setMsg(msg);
        matters.preInsert();
        mattersService.save(matters);
        return taskDao.changeParticipant(id, participantId,participantAfter);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeExecutor(Long id, Long executorId) {
        //查询修改前信息
        Task taskBefore = taskDao.getById(id);
        User user = userDao.getById(executorId);
        //修改前负责人
        String executorBefore = taskBefore.getExecutorName();
        //修改后负责人
        String executorAfter = user.getNickname();
        String msg = "修改负责人 " + executorBefore + " => " + executorAfter;
        Matters matters = new Matters();
        matters.setTaskId(id);
        matters.setMsg(msg);
        matters.preInsert();
        mattersService.save(matters);
        return taskDao.changeExecutor(id, executorId,executorAfter);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeActualTotalWorkingHours(Long id, Integer actualTotalWorkingHoursAfter) {
        //查询修改前信息
        Task taskBefore = taskDao.getById(id);
        //修改前登记工时
        Integer actualTotalWorkingHoursBefore = taskBefore.getActualTotalWorkingHours();
        String msg = "修改登记工时 " + actualTotalWorkingHoursBefore + " => " + actualTotalWorkingHoursAfter;
        Matters matters = new Matters();
        matters.setTaskId(id);
        matters.setMsg(msg);
        matters.preInsert();
        mattersService.save(matters);
        return taskDao.changeaAtualTotalWorkingHours(id, actualTotalWorkingHoursAfter);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeEstimateWorkingHours(Long id, Integer estimateWorkingHours) {
        //查询修改前信息
        Task taskBefore = taskDao.getById(id);
        //修改前预计工时
        Integer estimateWorkingHoursBefore = taskBefore.getEstimateWorkingHours();
        String msg = "修改预计工时 " + estimateWorkingHoursBefore + " => " + estimateWorkingHours;
        Matters matters = new Matters();
        matters.setTaskId(id);
        matters.setMsg(msg);
        matters.preInsert();
        mattersService.save(matters);
        return taskDao.changeEstimateWorkingHours(id, estimateWorkingHours);
    }

    /**
     * 修改截止日期
     * @param id
     * @param deadline
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeDeadline(Long id, Date deadline) {
        //查询修改前信息
        Task taskBefore = taskDao.getById(id);
        //修改前截止日期
        Date deadlineBefore = taskBefore.getDeadline();
        String msg = "修改截止日期 " + DateUtils.formatDate(deadlineBefore) + " => " + DateUtils.formatDate(deadline);
        Matters matters = new Matters();
        matters.setTaskId(id);
        matters.setMsg(msg);
        matters.preInsert();
        mattersService.save(matters);
        return taskDao.changeDeadline(id, deadline);
    }

    /**
     * 修改关联任务
     * @param id
     * @param conjunctionTaskId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeConjunctionTask(Long id, String conjunctionTaskId ,String conjunctionTaskName) {
        //查询修改前信息
        Task taskBefore = taskDao.getById(id);
        //判断是修改关联任务还是新增关联任务
        String msg = "";
        if(taskBefore.getConjunctionTaskId() != null){
            String  conjunctionTaskNameBefore =  taskBefore.getConjunctionTaskName();

             msg = "修改任务关联 " + conjunctionTaskNameBefore + " => " + conjunctionTaskName;
        }else{
             msg = "新增任务关联 " + conjunctionTaskName ;
        }
        Matters matters = new Matters();
        matters.setTaskId(id);
        matters.setMsg(msg);
        matters.preInsert();
        mattersService.save(matters);
        return taskDao.changeConjunctionTask(id, conjunctionTaskId ,conjunctionTaskName);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long save(Task task) {
        task.preInsert();
        Project project = projectDao.getById(task.getProjectId());
        task.setProjectName(project.getName());
        task.setExecutorId(project.getExecutorId());
        task.setExecutorName(project.getExecutorName());
        task.setActualTotalWorkingHours(0);
        task.setStatus(0);
        taskDao.save(task);
        log.debug("新增Task=>{}", task.getId());

        // 保存描述中@Users
        taskAtUsersService.deleteByTaskIdAndMattersId(task.getId(), 0L);
        if (task.getAtUsers() != null) {
            for (Long userId : task.getAtUsers()) {
                taskAtUsersService.save(new TaskAtUsers(task.getId(), 0L, userId));
            }
        }

        Matters matters = new Matters();
        matters.setTaskId(task.getId());
        matters.setMsg("添加了任务");
        matters.preInsert();
        mattersService.save(matters);

        return task.getId();
    }

    @Override
    public PageTableResponse list(PageTableRequest request) {
        Object orderBy = request.getParams().get("orderBy");
        // 置顶优先
        if (Objects.nonNull(orderBy)) {
            request.getParams().put("orderBy",
                    "order by isTop desc, " + StringUtils.substringAfter(request.getParams().get("orderBy").toString(),"order by"));
        }
        // 权限范围控制
        request.getParams().put("dsf", BaseService.dataScopeFilter("tms", UserUtil.getCurrentUser(), "d1,d2", "u1,u2,u3,u4,u5,u6"));
        return new PageTableHandler(
                request1 -> taskDao.count(request1.getParams()),
                request2 -> taskDao.list(
                        request2.getParams(), request2.getOffset(), request2.getLimit()))
                .handle(request);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateIsTop(Long taskId, Integer isTop) {
        Matters matters = new Matters(taskId, isTop == 1 ? "任务置顶" : "取消任务置顶", null, null);
        matters.preInsert();
        mattersService.save(matters);
        return taskDao.updateIsTop(taskId, isTop);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void timing() {
        log.info("test");
        User user = userDao.getUser("liutao");
        user.setStatus(2);
        userDao.update(user);
    }


}
